﻿using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using System.Web.Routing;
using BlankMvc.Types;

namespace BlankMvc.Controllers.Base {
	public abstract class BaseController : Controller {

		protected const string CONTENT = "#content";
		protected const string DIALOG = "#dialogsContainer";

		protected ActionResult RedirectBase(string action, string controller) {
			string url = UrlHelper.GenerateUrl("", action, controller, Request.Url.Scheme, Request.Url.Host, null, null, RouteTable.Routes, ControllerContext.RequestContext, false);
			JsonData dat = new JsonData { Redirect = url };
			return new JsonResult { Data = dat };
		}

		protected ActionResult ViewBase(string[] selectors, string[] viewName, object[] models) {
			if (viewName.Length != selectors.Length) {
				throw new Exception("Количество селекторов и видов должно быть одинаково");
			}
			CheckTitle();
			JsonData dat = new JsonData { Title = ViewBag.Title };
			for (int i = 0; i < selectors.Length; i++) {
				Replacer rpl = new Replacer {
					Select = selectors[i],
					Data = RenderView(viewName[i], models[i])
				};
				dat.Repl.Add(rpl);
			}
			return new JsonResult { Data = dat };
		}

		protected ActionResult ViewBase(string selector) {
			return ViewBase(selector, null);
		}

		protected ActionResult ViewBase(string selector, string viewName) {
			return ViewBase(selector, viewName, new { });
		}

		protected ActionResult ViewBase(string selector, string viewName, object model) {
			if (string.IsNullOrEmpty(selector)) {
				throw new Exception("Необходим селектор");
			}
			if (string.IsNullOrEmpty(viewName)) {
				viewName = ControllerContext.RouteData.GetRequiredString("action");
			}
			DataView dv = new DataView { View = viewName, Model = model, Selector = selector };
			return ViewBase(dv);
		}

		public ActionResult ViewBase(DataView dv) {
			CheckTitle();
			return Request.IsAjaxRequest() ? ViewJson(dv, ViewBag.Title) : View(dv.View, dv.Model);
		}

		protected ActionResult ViewJson(DataView dv, string pageTitle) {
			JsonData dat = new JsonData { Title = pageTitle };
			dat.Repl.Add(new Replacer { Select = dv.Selector, Data = RenderView(dv.View, dv.Model) });
			return new JsonResult {
				Data = dat,
				JsonRequestBehavior = JsonRequestBehavior.AllowGet
			};
		}

		protected string RenderView(string viewName, object model) {
			if (string.IsNullOrEmpty(viewName))
				return string.Empty;
			using (StringWriter sw = new StringWriter()) {
				ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
				ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
				viewResult.View.Render(viewContext, sw);
				return sw.GetStringBuilder().ToString();
			}
		}

		private void CheckTitle() {
			if (ViewBag.Title == null) {
				string action = ControllerContext.RouteData.GetRequiredString("action");
				try {
					MethodInfo[] arrInf = GetType().GetMethods();
					MethodInfo mInf = arrInf.First(m => m.Name == action);
					TitleAttribute attr = mInf.GetCustomAttributes(true).OfType<TitleAttribute>().First();
					ViewBag.Title = attr.Value;
				} catch {
					throw new Exception("Не указа заголовок страницы action: " + action);
				}
			}
		}
	}
}
